package com.leviassaf.firstandroidapp;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import android.os.Bundle;
import android.app.Activity;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.util.Base64;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;

import com.facebook.*;
import com.facebook.model.*;

import android.widget.TextView;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.Signature;

public class MainActivity extends FragmentActivity {

	private static final int SPLASH = 0;
	private static final int SELECTION = 1;
	private static final int SETTINGS = 2;
	private static final int FRAGMENT_COUNT = SETTINGS + 1;
	private Fragment[] fragments = new Fragment[FRAGMENT_COUNT];
	
	//variable to represent the menu item for the settings fragment. 
	//Used this to trigger the UserSettingsFragment display
	private MenuItem menuItemSettings;

	//flag that indicates a visible activity. This flag is used to enable session state change checks
	private boolean booIsResumed = false;
	
	//UiLifecycleHelper is used to track the session and trigger a session state change listener
	private UiLifecycleHelper uiLifecycleHelper;
	//pass the listener to the constructor
	private Session.StatusCallback statusCallback = new Session.StatusCallback() {
		
		@Override
		public void call(Session session, SessionState state, Exception exception) {
			//call onSessionStateChange to respond to session state changes and show the relevant fragment
			onSessionStateChange(session, state, exception);
		}
	};
	
	protected void onSaveInstanceState(Bundle outState) {
		super.onSaveInstanceState(outState);
		//call the UiLifecycleHelper activity onSaveInstanceState method that is needed to properly keep track of the session
		uiLifecycleHelper.onSaveInstanceState(outState);
	};

	public void onDestroy() {
		super.onDestroy();
		//call the UiLifecycleHelper activity onDestroy method that is needed to properly keep track of the session
		uiLifecycleHelper.onDestroy();
	};
	
	@Override
	protected void onResume() {
		super.onResume();
		//call the UiLifecycleHelper activity onResume method that is needed to properly keep track of the session
		uiLifecycleHelper.onResume();
		booIsResumed = true;
	}
	
	@Override
	protected void onPause() {
		super.onPause();
		//call the UiLifecycleHelper activity onPause method that is needed to properly keep track of the session
		uiLifecycleHelper.onPause();
		booIsResumed = false;
	}
	
	//This method shows the relevant fragment based on the person's authenticated state. 
	//Only handle UI changes when the activity is visible by making use of the isResumed flag. 
	//The fragment back stack is first cleared before the showFragment() method is called with the appropriate fragment info
	private void onSessionStateChange (Session session, SessionState sessionState, Exception exception){
		//Only make changes if the activity is visible
		if (booIsResumed){
			//Before the relevant fragment is shown, the fragment back stack is cleared
			FragmentManager fragmentManager = getSupportFragmentManager();
			//Get the number of entries in the back stack
			int intBackStackSize = fragmentManager.getBackStackEntryCount();
			//Clear the back stack
			for (int i = 0; i < intBackStackSize; i++){
				fragmentManager.popBackStack();
			}
			if (sessionState.isOpened()){
				//If the session state is open, show the authenticated fragment
				showFragment(SELECTION, true);
			}
			else if (sessionState.isClosed()){
				//If the session state is closed, show the login fragment
				showFragment(SPLASH, true);
			}
		}
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);
		//call the UiLifecycleHelper activity onActivityResult method that is needed to properly keep track of the session
		uiLifecycleHelper.onActivityResult(requestCode, resultCode, data);
		Session.getActiveSession().onActivityResult(this, requestCode,
				resultCode, data);
	}
	
	//Whenever a fragment is resumed, check the person's session state and handle showing the authenticated or nonauthenticated UI.
	@Override
	protected void onResumeFragments() {
		super.onResumeFragments();
		Session session = Session.getActiveSession();
		if (session != null && session.isOpened()){
			//if the session is already open, try to show the selection fragment
			showFragment(SELECTION, true);
		}
		else{
			//otherwise present the splash screen and ask the person to login
			showFragment(SPLASH, true);
		}
	}

	//method that is responsible for showing a given fragment and hiding all other fragments
	private void showFragment(int fragmentIndex, boolean addToBackStack) {
		FragmentManager fragmentManager = getSupportFragmentManager();
		FragmentTransaction fragmentTransaction = fragmentManager
				.beginTransaction();
		for (int i = 0; i < fragments.length; i++) {
			if (i == fragmentIndex) {
				fragmentTransaction.show(fragments[i]);
			} else {
				fragmentTransaction.hide(fragments[i]);
			}
		}
		if (addToBackStack){
			fragmentTransaction.addToBackStack(null);
		}
		fragmentTransaction.commit();
	}

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		
		//pass the Session.StatusCallback listener to the constructor
		uiLifecycleHelper = new UiLifecycleHelper(this, statusCallback);
		//call the UiLifecycleHelper activity onCreate method that is needed to properly keep track of the session
		uiLifecycleHelper.onCreate(savedInstanceState);

		setContentView(R.layout.activity_main);

		FragmentManager fragmentManager = getSupportFragmentManager();
		fragments[SPLASH] = fragmentManager.findFragmentById(R.id.fragmentSplash);
		fragments[SELECTION] = fragmentManager.findFragmentById(R.id.fragmentSelection);
		fragments[SETTINGS] = fragmentManager.findFragmentById(R.id.fragmentUserSettings);
		FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
		//hide the fragments initially
		for (int i = 0; i < fragments.length; i++) {
			fragmentTransaction.hide(fragments[i]);
		}
		fragmentTransaction.commit();
	}


	//prepare the options menu display
	@Override
	public boolean onPrepareOptionsMenu(Menu menu) {
		//only add the menu when the selection fragment is showing
		if (fragments[SELECTION].isVisible()){
			if (menu.size() == 0){
				menuItemSettings = menu.add(R.string.settings);
			}
			return true;
		}
		else{
			menu.clear();
			menuItemSettings = null;
		}
		return false;
	}

	//display the UserSettingsFragment when the settings menu is clicked
	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		if (item.equals(menuItemSettings)){
			showFragment(SETTINGS, true);
			return true;
		}
		return false;
	}

}
